#include "data.hpp"
#include "httplib2/httplib.h"

namespace ctv{

#define WWWROOT "./www"
#define VIDEO_ROOT "/video/"
#define IMAGE_ROOT "/image/"

    TableVideo *tb_video = NULL;

    class Server{
        private:
            int _port;
            httplib::Server _srv;
        private:
            static void Insert(const httplib::Request &req, httplib::Response &rsp)
            {
                if(req.has_file("name") == false||
                req.has_file("info") == false||
                req.has_file("video") == false||
                req.has_file("image") == false){
                    rsp.status = 400;
                    rsp.body = R"({"result":false, "reason":"上传格式出错"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                httplib::MultipartFormData name = req.get_file_value("name");
                httplib::MultipartFormData info = req.get_file_value("info");
                httplib::MultipartFormData video = req.get_file_value("video");
                httplib::MultipartFormData image = req.get_file_value("image");
                
                std::string video_name = name.content;
                std::string video_info = info.content;

                std::string root = WWWROOT;
                std::string  video_path = root + VIDEO_ROOT + video.name + video.filename;
                std::string  image_path = root + IMAGE_ROOT + video.name + image.filename;

                if(FileUtil(video_path).SetContent(video.content) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"视频文件存储失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                if(FileUtil(image_path).SetContent(image.content) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"图片文件存储失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                //保存到数据库
                Json::Value Video_json;
                Video_json["name"] = video_name;
                Video_json["info"] = video_info;
                Video_json["video"] = VIDEO_ROOT + video.name + video.filename;
                Video_json["image"] = IMAGE_ROOT + video.name + image.filename;

                if(tb_video->Insert(Video_json) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"数据库新增数据失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }
                rsp.set_redirect("/index.html", 303);
                return;

            }

            static void Update(const httplib::Request &req, httplib::Response &rsp)
            {
                //获取id
                int video_id = std::stoi(req.matches[1]);
                Json::Value video;
                if(JsonUtil::UnSerialize(req.body, &video) == false)
                {
                    rsp.status = 400;
                    rsp.body = R"({"result":false, "reason":"视频解析错误"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                if(tb_video->Updata(video_id, video) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"数据库修改数据失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }
                return;
            }
            static void Delete(const httplib::Request &req, httplib::Response &rsp)
            {
                //获取视频id
                int video_id = std::stoi(req.matches[1]);
                //删除视频文件
                Json::Value video;
                if(tb_video->SelectOne(video_id, &video) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"要删除的视频不存在哦宝宝~~"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                std::string root = WWWROOT;
                std::string video_path = root + video["video"].asString();                
                std::string image_path = root + video["image"].asString();
                remove(video_path.c_str());                
                remove(image_path.c_str());


                //删除数据库
                if(tb_video->Delete(video_id) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"删除数据库信息失败了哦宝宝~~"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;                    
                }                

            }

            static void SelectOne(const httplib::Request &req, httplib::Response &rsp)
            {
                //获取视频id
                int video_id = stoi(req.matches[1]);
                //指定查询信息
                Json::Value video;
                if(tb_video->SelectOne(video_id, &video) == false)
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"对不起数据库出问题了~~"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;                    
                }
                //响应正文
                JsonUtil::Serialize(video, &rsp.body);
                rsp.set_header("Content-Type", "application/json");

                return;
            }

            static void SelectAll(const httplib::Request &req, httplib::Response &rsp)
            {
                //查询所有
                bool select_flag = true;

                std::string search_key;
                if(req.has_param("search") == true)
                {
                    select_flag = false;//模糊匹配
                    search_key = req.get_param_value("search");
                }

                Json::Value videos;
                if(select_flag == true)
                {
                    if(tb_video->SelectAll(&videos) == false)
                    {
                        rsp.status = 500;
                        rsp.body = R"({"result":false, "reason":"查询失败，系统错误~~"})";
                        rsp.set_header("Content-Type", "application/json");
                        return;
                    }
                }
                else
                {
                    if(tb_video->SelsctLike(search_key, &videos) == false)
                    {
                        std:: cout << "11" << std::endl;
                        rsp.status = 500;
                        rsp.body = R"({"result":false, "reason":"查询失败，系统错误(~~"})";
                        rsp.set_header("Content-Type", "application/json");
                        return;       
                    }
                }


                //序列化响应客户端
                JsonUtil::Serialize(videos, &rsp.body);
                rsp.set_header("Content-Type", "application/json");

                return;
            }
        
        public:
            //构造 
            Server(int port):_port(port){}
            bool RunModule()
            {
                //初始化数据管理，创建指定目录
                tb_video = new TableVideo();
                FileUtil(WWWROOT).CreateDiretory();
                std::string root = WWWROOT;
                std::string video_real_path = root + VIDEO_ROOT;
                FileUtil(video_real_path).CreateDiretory();
                std::string image_real_path = root + IMAGE_ROOT;
                FileUtil(image_real_path).CreateDiretory();
                

                //搭建http
                //设置静态资源根目录
                _srv.set_mount_point("/", WWWROOT);
                //设置对应关系
                _srv.Post("/video", Insert);
                _srv.Delete("/video/(\\d+)", Delete);
                _srv.Put("/video/(\\d+)", Update);
                _srv.Get("/video/(\\d+)", SelectOne);
                _srv.Get("/video", SelectAll);
                //启动服务器
                _srv.listen("0.0.0.0", _port);
                return true;
            }
    };
}
